package com.example.friend.service.question.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.common.core.constants.Constants;
import com.example.common.core.domain.TableDataInfo;
import com.example.friend.domain.question.Question;
import com.example.friend.domain.question.dto.QuestionQueryDTO;
import com.example.friend.domain.question.es.QuestionES;
import com.example.friend.domain.question.vo.QuestionDetailVO;
import com.example.friend.domain.question.vo.QuestionVO;
import com.example.friend.elasticsearch.QuestionRepository;
import com.example.friend.manager.QuestionCacheManager;
import com.example.friend.mapper.question.QuestionMapper;
import com.example.friend.mapper.user.UserSubmitMapper;
import com.example.friend.service.question.IQuestionService;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class QuestionServiceImpl implements IQuestionService {
    
    @Autowired
    private QuestionRepository questionRepository;

    @Autowired
    private QuestionMapper  questionMapper;

    @Autowired
    private QuestionCacheManager questionCacheManager;

    @Autowired
    private UserSubmitMapper userSubmitMapper;


    @Override
    public TableDataInfo list(QuestionQueryDTO questionQueryDTO) {
        // 获取 Elasticsearch 中题目总数
        long count = questionRepository.count();
        // 如果没有数据，则从数据库加载题目到 Elasticsearch
        if (count <= 0) {
            refreshQuestion();
        }

        // 构建排序条件：按 createTime 字段降序排列
        Sort sort = Sort.by(Sort.Direction.DESC, "createTime");

        // 构建分页参数对象 Pageable，pageNum 从 1 开始，需要转换为从 0 开始
        Pageable pageable = PageRequest.of(questionQueryDTO.getPageNum() - 1,
                questionQueryDTO.getPageSize(),
                sort);

        // 提取查询条件参数
        Integer difficulty = questionQueryDTO.getDifficulty(); // 难度等级
        String keyword = questionQueryDTO.getKeyword(); // 关键字（用于标题或内容搜索）

        // 声明分页结果变量
        Page<QuestionES> questionESPage;

        // 根据不同的查询条件组合执行对应的 Elasticsearch 查询方法
        if (difficulty == null && StrUtil.isEmpty(keyword)) {
            // 无难度、无关键字：查询所有题目
            questionESPage = questionRepository.findAll(pageable);
        } else if (StrUtil.isEmpty(keyword)) {
            // 有难度、无关键字：根据难度查询题目
            questionESPage = questionRepository.findQuestionByDifficulty(difficulty, pageable);
        } else if (difficulty == null) {
            // 无难度、有关键字：根据关键字在标题或内容中查询
            questionESPage = questionRepository.findByTitleOrContent(keyword, keyword, pageable);
        } else {
            // 同时有难度和关键字：联合查询
            questionESPage = questionRepository.findByTitleOrContentAndDifficulty(keyword, keyword, difficulty, pageable);
        }

        // 获取总记录数
        long total = questionESPage.getTotalElements();
        if (total == 0) {
            // 如果没有结果，返回空的 TableDataInfo 对象
            return TableDataInfo.empty();
        }

        // 获取当前页的数据内容
        List<QuestionES> questionESList = questionESPage.getContent();

        // 将 Elasticsearch 实体列表转换为 VO（视图对象）列表，供前端使用
        List<QuestionVO> questionVOList = BeanUtil.copyToList(questionESList, QuestionVO.class);

        // 返回成功响应，包含数据列表和总记录数
        return TableDataInfo.success(questionVOList, total);
    }

    @Override
    public List<QuestionVO> hotList() {
        Long total = questionCacheManager.getHostListSize();
        List<Long> hotQuestionIdList;
        if (total == null || total <= 0) {
            PageHelper.startPage(Constants.HOST_QUESTION_LIST_START, Constants.HOST_QUESTION_LIST_END);
            hotQuestionIdList = userSubmitMapper.selectHostQuestionList();
            questionCacheManager.refreshHotQuestionList(hotQuestionIdList);
        } else {
            hotQuestionIdList = questionCacheManager.getHostList();
        }
        return assembleQuestionVOList(hotQuestionIdList);
    }

    @Override
    public QuestionDetailVO detail(Long questionId) {
        QuestionES questionES = questionRepository.findById(questionId).orElse(null);
        QuestionDetailVO questionDetailVO = new QuestionDetailVO();
        if (questionES != null) {
            BeanUtil.copyProperties(questionES, questionDetailVO);
            return questionDetailVO;
        }
        Question question = questionMapper.selectById(questionId);
        if (question == null) {
            return null;
        }
        refreshQuestion();
        BeanUtil.copyProperties(question, questionDetailVO);
        return questionDetailVO;
    }

    @Override
    public String preQuestion(Long questionId) {
        Long listSize = questionCacheManager.getListSize();
        if(listSize == null || listSize <= 0) {
            questionCacheManager.refreshCache();
        }
        return questionCacheManager.preQuestion(questionId).toString();
    }

    @Override
    public String nextQuestion(Long questionId) {
        Long listSize = questionCacheManager.getListSize();
        if(listSize == null || listSize <= 0) {
            questionCacheManager.refreshCache();
        }
        return questionCacheManager.nextQuestion(questionId).toString();
    }


    private void refreshQuestion() {
        List<Question> questionList = questionMapper.selectList(new LambdaQueryWrapper<Question>());
        if (CollectionUtil.isEmpty(questionList)){
            return;
        }
        // 类型转换 List<Question> -> List<QuestionES>
        List<QuestionES> questionESList = BeanUtil.copyToList(questionList, QuestionES.class);
        questionRepository.saveAll(questionESList);

    }

    private List<QuestionVO> assembleQuestionVOList(List<Long> hotQuestionIdList) {
        if (CollectionUtil.isEmpty(hotQuestionIdList)) {
            return new ArrayList<>();
        }
        List<QuestionVO> resultList = new ArrayList<>();
        for (Long questionId : hotQuestionIdList) {
            QuestionVO questionVO = new QuestionVO();
            QuestionDetailVO detail = detail(questionId);
            questionVO.setTitle(detail.getTitle());
            resultList.add(questionVO);
        }
        return resultList;
    }
}
